home *** CD-ROM | disk | FTP | other *** search
/ Amiga Format CD 22 / Amiga Format AFCD22 (Jan 1998, Issue 106).iso / -in_the_mag- / converters / graphics / netpbm / hpcdtoppm.0.6 / src / format.c < prev    next >
C/C++ Source or Header  |  1997-11-16  |  19KB  |  745 lines

  1. /* hpcdtoppm (Hadmut's pcdtoppm) v0.6
  2. *  Copyright (c) 1992, 1993, 1994 by Hadmut Danisch (danisch@ira.uka.de).
  3. *  Permission to use and distribute this software and its
  4. *  documentation for noncommercial use and without fee is hereby granted,
  5. *  provided that the above copyright notice appear in all copies and that
  6. *  both that copyright notice and this permission notice appear in
  7. *  supporting documentation. It is not allowed to sell this software in 
  8. *  any way. This software is not public domain.
  9. */
  10.  
  11. #include "hpcdtoppm.h"
  12.  
  13. struct pcdquad { uBYTE len,highseq,lowseq,key;};
  14. struct pcdhqt  { uBYTE entries; struct pcdquad entry[256];};
  15. struct myhqt   { uINT seq,mask,len; uBYTE key; };
  16.  
  17. static struct myhqt myhuff0[256],myhuff1[256],myhuff2[256];
  18. static sINT          myhufflen0=0,myhufflen1=0,myhufflen2=0;
  19.  
  20.  
  21.  
  22.  
  23. static void readhqtsub(struct pcdhqt *quelle,struct myhqt *ziel,sINT *anzahl)
  24. #define E ((uINT) 1)
  25.  {sINT i;
  26.   struct pcdquad *sub;
  27.   struct myhqt *help;
  28.   *anzahl=(quelle->entries)+1;
  29.  
  30.   for(i=0;i<*anzahl;i++)
  31.    {sub = (struct pcdquad *)(((uBYTE *)quelle)+1+i*sizeof(*sub));
  32.     help=ziel+i;
  33.  
  34.     help->seq = (((uINT) sub->highseq) << 24) |(((uINT) sub->lowseq) << 16);
  35.     help->len = ((uINT) sub->len) +1;
  36.     help->key = sub->key;
  37.  
  38. #ifdef DEBUGhuff
  39.    fprintf(stderr," Anz: %d A1: %08x  A2: %08x X:%02x %02x %02x %02x Seq:  %08x   Laenge:  %d %d\n",
  40.           *anzahl,(uINT)sbuffer,(uINT)sub,
  41.           ((uBYTE *)sub)[0],((uBYTE *)sub)[1],((uBYTE *)sub)[2],((uBYTE *)sub)[3],
  42.           help->seq,help->len,sizeof(uBYTE));
  43. #endif
  44.  
  45.     if(help->len > 16) error(E_HUFF);
  46.  
  47.     help->mask = ~ ( (E << (32-help->len)) -1); 
  48.  
  49.   }
  50. #ifdef DEBUG
  51.   for(i=0;i<*anzahl;i++)
  52.    {help=ziel+i;
  53.     fprintf(stderr,"H: %3d  %08lx & %08lx (%2d) = %02x = %5d  %8x\n",
  54.         i, help->seq,help->mask,help->len,help->key,(sBYTE)help->key,
  55.         help->seq & (~help->mask));
  56.    }
  57. #endif
  58.  
  59. #undef E
  60. }
  61.  
  62.  
  63.  
  64.  
  65.  
  66.  
  67.  
  68. void readhqt(sINT n)
  69.  {
  70.   uBYTE *ptr;
  71.  
  72.   melde("readhqt\n");
  73.   EREADBUF;
  74.   ptr = sbuffer;
  75.  
  76.   readhqtsub((struct pcdhqt *)ptr,myhuff0,&myhufflen0);
  77.  
  78.   if(n<2) return;
  79.   ptr+= 1 + 4* myhufflen0;
  80.   readhqtsub((struct pcdhqt *)ptr,myhuff1,&myhufflen1);
  81.  
  82.   if(n<3) return;
  83.   ptr+= 1 + 4* myhufflen1;
  84.   readhqtsub((struct pcdhqt *)ptr,myhuff2,&myhufflen2);
  85.  
  86. }
  87.  
  88. void readhqtx(sINT n)
  89.  {
  90.   uBYTE *ptr;
  91.  
  92.   melde("readhqtx\n");
  93.   ptr = sbuffer;
  94.  
  95.   readhqtsub((struct pcdhqt *)ptr,myhuff0,&myhufflen0);
  96.  
  97.   if(n<2) return;
  98.   ptr+= 1 + 4* myhufflen0;
  99.   readhqtsub((struct pcdhqt *)ptr,myhuff1,&myhufflen1);
  100.  
  101.   if(n<3) return;
  102.   ptr+= 1 + 4* myhufflen1;
  103.   readhqtsub((struct pcdhqt *)ptr,myhuff2,&myhufflen2);
  104.  
  105. }
  106.  
  107.  
  108.  
  109.  
  110.  
  111.  
  112.  
  113.  
  114.  
  115. #ifdef FASTHUFF
  116.  
  117. static struct myhqt *HTAB0[0x10000],*HTAB1[0x10000],*HTAB2[0x10000];
  118.  
  119. static void inithuff(sINT hlen,struct myhqt *ptr,struct myhqt *TAB[])
  120.  {sINT i,n;
  121.   sINT seq,len;
  122.   struct myhqt *help;
  123.  
  124.   for(i=0;i<0x10000;i++) TAB[i]=0;
  125.  
  126.   for(n=0;n<hlen;n++)
  127.    {help=ptr+n;
  128.     seq=(help->seq)>>16;
  129.     len=help->len;
  130.  
  131.     for(i=0;i<(1<<(16-len));i++)
  132.       TAB[seq | i] = help;
  133.    }
  134.  }
  135. #endif
  136.  
  137.  
  138.  
  139.  
  140. static char *pn[]={"Luma Channel","Chroma1 Channel","Chroma2 Channel"};
  141.  
  142.  
  143. void decode(sizeinfo *si,int fak,implane *f,implane *f1,implane *f2,sINT autosync)
  144.  {dim w,h,hoff,hlen,hende,voff,vlen,vende,anfang,ende;
  145.   sINT htlen,sum,do_inform,part;
  146.   uINT sreg,maxwidth;
  147.   uINT inh,n,zeile,segment,ident;
  148.   struct myhqt *hp;
  149.  
  150.   uBYTE *nptr;
  151.   uBYTE *lptr;
  152.  
  153. #define nextbuf  {  nptr=sbuffer; if(READBUF<1) { if(!do_rep) error(E_READ); \
  154.                                                   fprintf(stderr,"Read error\n"); \
  155.                                                   return; } }
  156. #define checkbuf { if (nptr >= sbuffer + sizeof(sbuffer)) nextbuf; }
  157.  
  158. #ifdef U_TOO_LONG
  159. #define shiftreg(n) sreg = (sreg<< n ) & 0xffffffff;
  160. #else
  161. #define shiftreg(n) sreg<<=n;
  162. #endif
  163.  
  164. #define shiftout(n){ shiftreg(n); inh-=n; \
  165.                      while (inh<=24) \
  166.                       {checkbuf; \
  167.                        sreg |= ((uINT)(*(nptr++)))<<(24-inh);\
  168.                        inh+=8;\
  169.                       }\
  170.                     }  
  171. #define issync     ((sreg & 0xffffff00) == 0xfffffe00) 
  172. #define brutesync  ((sreg & 0x00fff000) == 0x00fff000) 
  173. #define seeksync { while (!brutesync) shiftout(8); while (!issync) shiftout(1);}
  174.  
  175. #ifdef FASTHUFF
  176.   struct myhqt **HTAB;
  177.   HTAB=0;
  178.   inithuff(myhufflen0,myhuff0,HTAB0);
  179.   inithuff(myhufflen1,myhuff1,HTAB1);
  180.   inithuff(myhufflen2,myhuff2,HTAB2);
  181. #define SETHUFF0 HTAB=HTAB0;
  182. #define SETHUFF1 HTAB=HTAB1;
  183. #define SETHUFF2 HTAB=HTAB2;
  184. #define FINDHUFF(x) {x=HTAB[sreg>>16];}
  185.  
  186. #else
  187.  
  188.   sINT i;
  189.   struct myhqt *htptr;
  190.   htptr=0;
  191. #define SETHUFF0 { htlen=myhufflen0 ; htptr = myhuff0 ; }
  192. #define SETHUFF1 { htlen=myhufflen1 ; htptr = myhuff1 ; }
  193. #define SETHUFF2 { htlen=myhufflen2 ; htptr = myhuff2 ; }
  194. #define FINDHUFF(x)  {for(i=0, x=htptr;(i<htlen) && ((sreg & x ->mask)!= x->seq); i++,x++); \
  195.                       if(i>=htlen) x=0;}
  196. #endif
  197.  
  198.   melde("decode\n");
  199.   anfang=ende=0;
  200.  
  201.   if(fak >= 0)
  202.    {w   =si->w     *fak;
  203.     h   =si->h     *fak;
  204.     hoff=si->rdhoff*fak;  if(hoff & 1 ) error(E_INTERN);  /* Must be all even */
  205.     hlen=si->rdhlen*fak;  if(hlen & 1 ) error(E_INTERN); hende=hlen+hoff;
  206.     voff=si->rdvoff*fak;  if(voff & 1 ) error(E_INTERN);
  207.     vlen=si->rdvlen*fak;  if(vlen & 1 ) error(E_INTERN); vende=vlen+voff;
  208.    }
  209.   else
  210.    {fak = -fak;
  211.     w   =si->w     /fak;
  212.     h   =si->h     /fak;
  213.     hoff=si->rdhoff/fak;  if(hoff & 1 ) error(E_INTERN);  /* Must be all even */
  214.     hlen=si->rdhlen/fak;  if(hlen & 1 ) error(E_INTERN); hende=hlen+hoff; 
  215.     voff=si->rdvoff/fak;  if(voff & 1 ) error(E_INTERN);
  216.     vlen=si->rdvlen/fak;  if(vlen & 1 ) error(E_INTERN); vende=vlen+voff;
  217.    }
  218.  
  219.  
  220.   if( f  && ((! f->im) || ( f->iheight != vlen  ) ||  (f->iwidth != hlen  ))) error(E_INTERN);
  221.   if( f1 && ((!f1->im) || (f1->iheight != vlen/2) || (f1->iwidth != hlen/2))) error(E_INTERN);
  222.   if( f2 && ((!f2->im) || (f2->iheight != vlen/2) || (f2->iwidth != hlen/2))) error(E_INTERN);
  223.  
  224.   htlen=sreg=maxwidth=0;
  225.   zeile=0;
  226.   nextbuf;
  227.   inh=32;
  228.   lptr=0;
  229.   part=do_inform=0;
  230.   shiftout(16);
  231.   shiftout(16);
  232.  
  233.   if(autosync) seeksync;
  234.   
  235.   if(!issync)
  236.    { if(!do_rep) error(E_SEQ6);
  237.      else 
  238.       {fprintf(stderr,"Image does not start with synchron mark, seeking...\n");
  239.        seeksync;
  240.        do_inform=1;
  241.       }
  242.    }
  243.  
  244.   n=0;
  245.  
  246.   for(;;)
  247.    {
  248.     if (issync)
  249.      {shiftout(24);
  250.       ident=sreg>>16;
  251.       shiftout(16);
  252.  
  253.       zeile=(ident>>1) & 0x1fff;
  254.       segment=ident>>14;
  255.       if(do_inform) {fprintf(stderr,"Synchron mark found Line %d\n",zeile);do_inform=0;}
  256. #ifdef DEBUG
  257.       fprintf(stderr,"Id %4x Zeile: %6d Seg %3d Pix bisher: %5d  Position: %8lx+%5lx=%8x\n",
  258.           ident,zeile,segment,n,bufpos,nptr-sbuffer,bufpos+nptr-sbuffer);
  259. #endif
  260.  
  261.  
  262.       if(lptr && (n!=maxwidth)) 
  263.        {if(!do_rep)error(E_SEQ1);
  264.         else fprintf(stderr,"Line %d in %s : wrong length of last line (%d)\n",zeile,pn[part],n);
  265.        }
  266.       n=0;
  267.  
  268.       if(zeile==h) {RPRINT; return; }
  269.       if(zeile >h) 
  270.        { if(!do_rep) error(E_SEQ2);
  271.          else 
  272.           {fprintf(stderr,"Wrong line number %d, ignoring line\n",zeile);
  273.            seeksync;
  274.            n=maxwidth;
  275.            do_inform=1;
  276.           }
  277.        }    
  278.       else switch(segment)
  279.        {
  280.         case 1: if(!do_rep) error(E_SEQ3);
  281.                 fprintf(stderr,"Abnormal line tag in %d, interpreting as Luma tag\n",zeile);
  282.         case 0: maxwidth=w;
  283.                 if((!f) && autosync) {seeksync; n=maxwidth; break;}
  284.                 if(!f) error(E_SEQ7);
  285.                 if((zeile<voff) || (zeile >= vende)) {seeksync; n=maxwidth; break;}
  286.                 anfang=hoff; ende=hende;
  287.                 lptr=f->im + (zeile-voff)*f->mwidth;
  288.                 SETHUFF0;
  289.                 part=0;
  290.                 break;
  291.  
  292.         case 2: maxwidth=w>>1;
  293.                 if(!f1) return;
  294.                 /*if((!f1) && autosync) {seeksync; break;}*/
  295.                 if((zeile<voff) || (zeile >= vende)) {seeksync; n=maxwidth; break;}
  296.                 anfang=hoff>>1; ende=hende>>1;
  297.                 lptr=f1->im + ((zeile-voff)>>1)*f1->mwidth;
  298.                 SETHUFF1;
  299.                 part=1;
  300.                 break;
  301.  
  302.         case 3: maxwidth=w>>1;
  303.                 if(!f2) return;
  304.                 /*if((!f2) && autosync) {seeksync; break;}*/
  305.                 if((zeile<voff) || (zeile >= vende)) {seeksync; n=maxwidth; break;}
  306.                 anfang=hoff>>1; ende=hende>>1;
  307.                 lptr=f2->im + ((zeile-voff)>>1)*f2->mwidth;
  308.                 SETHUFF2;
  309.                 part=2;
  310.                 break;
  311.  
  312.         default:error(E_SEQ3);
  313.     }
  314.      }
  315.     else
  316.      {
  317.       if(!lptr)      error(E_SEQ6);
  318.  
  319.       if(n>maxwidth) 
  320.         {
  321. #ifdef DEBUG
  322.          fprintf(stderr,"Register: %08lx Pos: %08lx\n",sreg,bufpos+nptr-sbuffer);
  323. #endif
  324.          if (!do_rep) error(E_SEQ4);
  325.          else { fprintf(stderr,"Missing synchron mark in %s line %d\n",pn[part],zeile);
  326.                 seeksync;
  327.                 do_inform=1;
  328.                 n=maxwidth;
  329.               }
  330.        }
  331.       else
  332.        {FINDHUFF(hp);
  333.         if(!hp)
  334.          { if(!do_rep) error(E_SEQ5);
  335.            fprintf(stderr,"Unable to decode, ignoring rest of line\n");
  336.            seeksync;
  337.            n=maxwidth;
  338.            do_inform=1;
  339.          }
  340.         else
  341.          {if((n>= anfang) && (n<ende))
  342.            {sum=((sINT)(*lptr)) + ((sBYTE)hp->key);
  343.             NORM(sum);
  344.             *(lptr++) = sum;
  345.            }
  346.  
  347.           n++; 
  348.           shiftout(hp->len);
  349.          }
  350.        }
  351.      }
  352.  
  353.    }
  354.  
  355.  
  356. #undef nextbuf  
  357. #undef checkbuf 
  358. #undef shiftout
  359. #undef issync
  360. #undef seeksync
  361.  
  362.  }
  363.  
  364.  
  365.  
  366. /* Decode the 64Base files */
  367. void decodex(FILE **fp, int tag , struct ic_descr *descr,sizeinfo *si,int fak,implane *f,sINT autosync)
  368.  {dim w,h,hoff,hlen,hende,voff,vlen,vende,anfang,ende;
  369.   sINT htlen,sum,do_inform,part;
  370.   uINT sreg,maxwidth;
  371.   uINT inh,n,pos,zeile,segment,ident,sector,offset,length;
  372.   struct myhqt *hp;
  373.  
  374.   uBYTE *nptr;
  375.   uBYTE *lptr;
  376.  
  377.   int bufcont;
  378.  
  379.  
  380.  
  381. #define nextbuf  {  nptr=sbuffer; \
  382.                     do\
  383.                      {bufcont=fread(sbuffer,1,sizeof(sbuffer),*fp);\
  384.                       if(bufcont<1)\
  385.                        {if(feof(*fp)) fp++;\
  386.                         else if(!do_rep) error(E_READ);\
  387.                         else {fprintf(stderr,"Read error\n"); return;}\
  388.                         if(!*fp)      return; }\
  389.                      } while (bufcont<1); }
  390.  
  391.  
  392. #define checkbuf { if (nptr >= sbuffer + bufcont) nextbuf; }
  393.  
  394. #ifdef U_TOO_LONG
  395. #define shiftreg(n) sreg = (sreg<< n ) & 0xffffffff;
  396. #else
  397. #define shiftreg(n) sreg<<=n;
  398. #endif
  399.  
  400. #define shiftout(n){ shiftreg(n); inh-=n; \
  401.                      while (inh<=24) \
  402.                       {checkbuf; \
  403.                        sreg |= ((uINT)(*(nptr++)))<<(24-inh);\
  404.                        inh+=8;\
  405.                       }\
  406.                     }  
  407. #define issync     ((sreg & 0xffffff00) == 0xfffffe00) 
  408. #define brutesync  ((sreg & 0x00fff000) == 0x00fff000) 
  409. #define seeksync { while ((!brutesync) && (bufcont>0)) shiftout(8); \
  410.                    while ((!issync) && (bufcont>0)) shiftout(1);}
  411.  
  412. #ifdef FASTHUFF
  413.   struct myhqt **HTAB;
  414.   HTAB=0;
  415.   switch(tag)
  416.    {case 0:  inithuff(myhufflen0,myhuff0,HTAB0); break;
  417.     case 1:  inithuff(myhufflen1,myhuff1,HTAB1); break;
  418.     case 2:  inithuff(myhufflen2,myhuff2,HTAB2); break;
  419.     default: error(E_INTERN);
  420.    }
  421. #define SETHUFF0 HTAB=HTAB0;
  422. #define SETHUFF1 HTAB=HTAB1;
  423. #define SETHUFF2 HTAB=HTAB2;
  424. #define FINDHUFF(x) {x=HTAB[sreg>>16];}
  425.  
  426. #else
  427.  
  428.   sINT i;
  429.   struct myhqt *htptr;
  430.   htptr=0;
  431. #define SETHUFF0 { htlen=myhufflen0 ; htptr = myhuff0 ; }
  432. #define SETHUFF1 { htlen=myhufflen1 ; htptr = myhuff1 ; }
  433. #define SETHUFF2 { htlen=myhufflen2 ; htptr = myhuff2 ; }
  434. #define FINDHUFF(x)  {for(i=0, x=htptr;(i<htlen) && ((sreg & x ->mask)!= x->seq); i++,x++); \
  435.                       if(i>=htlen) x=0;}
  436. #endif
  437.  
  438.  
  439.  
  440.  
  441.  
  442.  
  443.  
  444.   melde("decodex\n");
  445.   anfang=ende=0;
  446.   maxwidth=FILE32(descr->length);
  447.   h       =FILE16(descr->height);
  448.   offset  =FILE16(descr->offset);
  449.   length  =FILE32(descr->length);
  450.  
  451.  
  452.   if(fak >= 0)
  453.    {w   =si->w     *fak;
  454.     h   =si->h     *fak;
  455.     hoff=si->rdhoff*fak;  if(hoff & 1 ) error(E_INTERN);  
  456.     hlen=si->rdhlen*fak;  if(hlen & 1 ) error(E_INTERN); hende=hlen+hoff;
  457.     voff=si->rdvoff*fak;  if(voff & 1 ) error(E_INTERN);
  458.     vlen=si->rdvlen*fak;  if(vlen & 1 ) error(E_INTERN); vende=vlen+voff;
  459.    }
  460.   else
  461.    {fak = -fak;
  462.     w   =si->w     /fak;
  463.     h   =si->h     /fak;
  464.     hoff=si->rdhoff/fak;  if(hoff & 1 ) error(E_INTERN);  
  465.     hlen=si->rdhlen/fak;  if(hlen & 1 ) error(E_INTERN); hende=hlen+hoff; 
  466.     voff=si->rdvoff/fak;  if(voff & 1 ) error(E_INTERN);
  467.     vlen=si->rdvlen/fak;  if(vlen & 1 ) error(E_INTERN); vende=vlen+voff;
  468.    }
  469.  
  470.  
  471.   if(!f) error(E_INTERN);
  472.  
  473. #ifdef DEBUG
  474.   fprintf(stderr,"fak %d\n",fak);
  475.   fprintf(stderr,"f->im %x  \n",(unsigned)f->im);
  476.   fprintf(stderr,"f->iheight  %d   %d\n",f->iheight,vlen);
  477.   fprintf(stderr,"f->iwidth   %d   %d\n",f->iwidth,hlen);
  478.   fprintf(stderr,"hoffset %d hende %d voffset %d vende %d\n",hoff,hende,voff,vende);
  479. #endif
  480.  
  481.   if((! f->im) || ( f->iheight != vlen  ) ||  (f->iwidth != hlen  )) error(E_INTERN);
  482.  
  483.  
  484.   switch(tag)
  485.    {case 0: SETHUFF0; break;
  486.     case 1: SETHUFF1; break;
  487.     case 2: SETHUFF2; break;
  488.     default: error(E_INTERN);
  489.    }
  490.  
  491.  
  492.  
  493.   htlen=sreg=0;
  494.   zeile=0;
  495.   nextbuf;
  496.   inh=32;
  497.   lptr=0;
  498.   part=do_inform=0;
  499.   shiftout(16);
  500.   shiftout(16);
  501.  
  502.   if(autosync) seeksync;
  503.   
  504.   if(!issync)
  505.    { if(!do_rep) error(E_SEQ6);
  506.      else 
  507.       {fprintf(stderr,"Image does not start with synchron mark, seeking...\n");
  508.        seeksync;
  509.        do_inform=1;
  510.       }
  511.    }
  512.  
  513.  
  514.   n=pos=0;
  515.  
  516.  
  517.   for(;;)
  518.    {if (issync)
  519.      {shiftout(24);
  520.       ident=(sreg>>8) & 0xffffff;
  521.       shiftout(24);
  522.  
  523.       segment=(ident>>20) & 0xf;
  524.       zeile  =(ident>>6 ) & 0x3fff;
  525.       sector =(ident>>1 ) & 0x1f;
  526.  
  527.       if(segment != tag) {fprintf(stderr,"Falsches Segment\n"); return;}
  528.       if(do_inform)      {fprintf(stderr,"Synchron mark found Line %d\n",zeile);do_inform=0;}
  529.  
  530.       if(zeile <  voff ) {n=maxwidth; seeksync; continue;}
  531.       if(zeile >= vende) return;
  532.    
  533.  
  534.  
  535. #ifdef DEBUG
  536.       fprintf(stderr,"Id %4x Zeile: %6d Seg %3d Sect %d Pix bisher: %5d \n",
  537.           ident,zeile,segment,sector,n);
  538. #endif
  539.  
  540.  
  541.       if(lptr && (n!=maxwidth)) 
  542.        {if(!do_rep)error(E_SEQ1);
  543.         else fprintf(stderr,"Line %d in %s : wrong length of last line (%d)\n",zeile,pn[part],n);
  544.        }
  545.  
  546.  
  547.       n=0;
  548.  
  549.       if(zeile==h) {RPRINT; return; }
  550.       if(zeile >h) 
  551.        { if(!do_rep) error(E_SEQ2);
  552.          else 
  553.           {fprintf(stderr,"Wrong line number %d, ignoring line\n",zeile);
  554.            seeksync;
  555.            n=maxwidth;
  556.            do_inform=1;
  557.           }
  558.        }    
  559.       else 
  560.         {switch(tag)
  561.           {case 0: anfang=hoff; ende=hende;
  562.                    pos=offset + sector*length;
  563.                    if((pos>=ende) || (pos+length < anfang)) { n=maxwidth; seeksync; continue;}
  564.                    lptr=f->im + (zeile-voff)*f->mwidth + (pos>anfang?(pos-anfang):0)  ;
  565.  
  566.                    break;
  567.            case 1:
  568.            case 2: anfang=hoff; ende=hende;
  569.                    pos=(offset>>1) + sector*length;
  570.                    if((pos>=ende) || (pos+length < anfang)) { n=maxwidth; seeksync; continue;}
  571.                    lptr=f->im + (zeile-voff)*f->mwidth + (pos>anfang?(pos-anfang):0)  ;
  572.  
  573.                    break;
  574.  
  575.  
  576.            default: error(E_INTERN);
  577.           }
  578.         }
  579.      }
  580.     else /* for if (issync) */
  581.      {if(!lptr)      error(E_SEQ6);
  582.  
  583.       FINDHUFF(hp);
  584.       if(!hp)
  585.        { if(!do_rep) error(E_SEQ5);
  586.          fprintf(stderr,"Unable to decode %08x, ignoring rest of line\n",sreg);
  587.          seeksync;
  588.          n=maxwidth;
  589.          do_inform=1;
  590.        }
  591.       else
  592.        {if((pos >= anfang) && (pos<ende)) 
  593.            {sum=((sINT)(*lptr)) + ((sBYTE)hp->key);    
  594.             NORM(sum);   
  595.             *(lptr++) = sum;  
  596.            }
  597.         n++; pos++;
  598.         shiftout(hp->len);
  599.         if(n==maxwidth) 
  600.          { if ((zeile >= vende -1) && (pos >= hende)) return;
  601.            seeksync;
  602.          }
  603.        }
  604.      }
  605.    }
  606.  
  607.  
  608.  
  609.  
  610. #undef nextbuf  
  611. #undef checkbuf 
  612. #undef shiftout
  613. #undef issync
  614. #undef seeksync
  615.  
  616.  }
  617.  
  618.  
  619.  
  620.  
  621.  
  622.  
  623.  
  624.  
  625.  
  626.  
  627.  
  628.  
  629. enum ERRORS readplain(sizeinfo *si,int fak,implane *l,implane *c1,implane *c2)
  630.  {dim i,w,h,hoff,hlen,voff,vlen;
  631.   uBYTE *pl=0,*pc1=0,*pc2=0;
  632.  
  633.   melde("readplain\n");
  634.  
  635. #ifdef DEBUG
  636.   fprintf(stderr,"readplain %d %d %d %d %d %d %d\n",fak,si->w,si->h,si->rdhoff,si->rdhlen,si->rdvoff,si->rdvlen);
  637. #endif
  638.  
  639.   if(fak >= 0)
  640.    {w   =si->w     *fak;
  641.     h   =si->h     *fak;
  642.     hoff=si->rdhoff*fak;  if(hoff & 1 ) error(E_INTERN);  /* Must be all even */
  643.     hlen=si->rdhlen*fak;  if(hlen & 1 ) error(E_INTERN);
  644.     voff=si->rdvoff*fak;  if(voff & 1 ) error(E_INTERN);
  645.     vlen=si->rdvlen*fak;  if(vlen & 1 ) error(E_INTERN);
  646.    }
  647.   else
  648.    {fak = -fak;
  649.     w   =si->w     /fak;
  650.     h   =si->h     /fak;
  651.     hoff=si->rdhoff/fak;  if(hoff & 1 ) error(E_INTERN);  /* Must be all even */
  652.     hlen=si->rdhlen/fak;  if(hlen & 1 ) error(E_INTERN);
  653.     voff=si->rdvoff/fak;  if(voff & 1 ) error(E_INTERN);
  654.     vlen=si->rdvlen/fak;  if(vlen & 1 ) error(E_INTERN);
  655.    }
  656.  
  657.  
  658.     
  659.   if(l)
  660.    { if ((l->mwidth<hlen) || (l->mheight<vlen) || (!l->im)) error(E_INTERN);
  661.      l->iwidth=hlen;
  662.      l->iheight=vlen;
  663.      pl=l->im;
  664.    }
  665.  
  666.   if(c1)
  667.    { if ((c1->mwidth<(hlen>>1)) || (c1->mheight<(vlen>>1)) || (!c1->im)) error(E_INTERN);
  668.      c1->iwidth=hlen>>1;
  669.      c1->iheight=vlen>>1;
  670.      pc1=c1->im;
  671.    }
  672.  
  673.   if(c2)
  674.    { if ((c2->mwidth<(hlen>>1)) || (c2->mheight<(vlen>>1)) || (!c2->im)) error(E_INTERN);
  675.      c2->iwidth=hlen>>1;
  676.      c2->iheight=vlen>>1;
  677.      pc2=c2->im;
  678.    }
  679.  
  680.   if(voff) SKIPr(w*3*(voff>>1));
  681.  
  682.   for(i=0;i<vlen>>1;i++)
  683.    {
  684.     if(pl)
  685.      { if(hlen==w)
  686.         {if(READ(pl,w)<1) return(E_READ);
  687.          pl+= l->mwidth;
  688.  
  689.          if(READ(pl,w)<1) return(E_READ);
  690.          pl+= l->mwidth;
  691.         }
  692.        else
  693.         {SKIPr(hoff);
  694.  
  695.          if(READ(pl,hlen)<1) return(E_READ);
  696.          pl+= l->mwidth;
  697.          
  698.          SKIPr(w-hlen);    /* w - hlen - hoff + hoff */ 
  699.  
  700.          if(READ(pl,hlen)<1) return(E_READ);
  701.          pl+= l->mwidth;
  702.  
  703.          SKIPr(w-hoff-hlen);         
  704.         }
  705.      }
  706.     else SKIPr(2*w);
  707.      
  708.     if(pc1)
  709.      {
  710.        if(hlen==w)
  711.         {
  712.          if(READ(pc1,w>>1)<1) return(E_READ);
  713.          pc1+= c1->mwidth;
  714.         }
  715.        else
  716.         {SKIPr((hoff)>>1);
  717.          if(READ(pc1,hlen>>1)<1) return(E_READ);
  718.          pc1+= c1->mwidth;
  719.          SKIPr((w-hoff-hlen)>>1);
  720.         }
  721.      }
  722.     else SKIPr(w>>1);
  723.      
  724.     if(pc2)
  725.      {
  726.        if(hlen==w)
  727.         {
  728.          if(READ(pc2,w>>1)<1) return(E_READ);
  729.          pc2+= c2->mwidth;
  730.         }
  731.        else
  732.         {SKIPr((hoff)>>1);
  733.          if(READ(pc2,hlen>>1)<1) return(E_READ);
  734.          pc2+= c2->mwidth;
  735.          SKIPr((w-hoff-hlen)>>1);
  736.         }
  737.      }
  738.     else SKIPr(w>>1);
  739.  
  740.  
  741.    }
  742.   RPRINT;
  743.   return E_NONE;
  744.  }
  745.